package com.newly.driver.sdk.device.video.service.impl.tencent;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.newly.driver.sdk.device.video.cloud.device.*;
import com.newly.driver.sdk.device.video.cloud.device.tencent.*;
import com.newly.driver.sdk.device.video.constants.DeviceConstant;
import com.newly.driver.sdk.device.video.exception.NewlyDeviceException;
import com.newly.driver.sdk.device.video.service.api.tencent.ITencentDevice;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.iotvideoindustry.v20201201.models.*;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author gjm guan
 * @date 2021/10/15 15:06
 * @desc 使用腾讯平台对设备做实现
 */
@Slf4j
public class TencentDevice extends AbstractTencentCloud implements ITencentDevice {

    @Override
    public CreateDeviceResp createDevice(CreateDeviceReq createDeviceReq) {
        try {
            Assert.notBlank(createDeviceReq.getName(), "name不能为空！");
            Assert.notNull(createDeviceReq.getType(), "type不能为空！");
            Assert.notNull(createDeviceReq.getPassword(), "password不能为空！");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 设置创建设备数据
        CreateDeviceRequest req = new CreateDeviceRequest();
        req.setNickName(createDeviceReq.getName()); // 设备名
        int deviceType = 2; // 设备类型
        int deviceTypeValue = createDeviceReq.getType().getKey();
        /*if (deviceTypeValue == DeviceConstant.VideoType.IPC.getKey()) {
            deviceType = 2;
        } else if (deviceTypeValue == DeviceConstant.VideoType.NVR.getKey()) {
            deviceType = 3;
        }*/
        req.setDeviceType((long) deviceType);
        req.setPassWord(createDeviceReq.getPassword()); // 设备密码
        if (!StrUtil.isBlank(createDeviceReq.getResGroupId())) {
            req.setGroupId(createDeviceReq.getResGroupId()); // 设备资源组
        }

        // 发起创建设备请求
        CreateDeviceResponse resp = null;
        try {
            resp = this.httpClient().CreateDevice(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("云设备创建失败: ", e);
        }

        // 解析响应数据
        CreateDeviceResp createDeviceResp = new CreateDeviceResp();
        createDeviceResp.setCode(0);
        createDeviceResp.setGbId(resp.getDeviceCode());
        createDeviceResp.setDeviceId(resp.getDeviceId());
        createDeviceResp.setResGroupId(resp.getVirtualGroupId());

        return createDeviceResp;
    }

    @Override
    public QueryDeviceResp listDevice(QueryDeviceReq queryDeviceReq) {
        DescribeAllDeviceListRequest req = new DescribeAllDeviceListRequest();
        req.setOffset((long) queryDeviceReq.getOffset());
        req.setLimit((long) queryDeviceReq.getLimit());
        List<String> deviceIds = queryDeviceReq.getDeviceIds();
        if (!ObjectUtil.isEmpty(deviceIds)) {
            String[] deviceIdArr = new String[deviceIds.size()];
            deviceIds.toArray(deviceIdArr);
            req.setDeviceIds(deviceIdArr);
        }
        DescribeAllDeviceListResponse resp = null;
        try {
            resp = this.httpClient().DescribeAllDeviceList(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("云设备查询失败");
        }
        // 封装响应参数
        QueryDeviceResp queryDeviceResp = new QueryDeviceResp();
        if (!ObjectUtil.isEmpty(resp)) {
            queryDeviceResp.setCode(0);
            queryDeviceResp.setTotal(resp.getTotalCount());
            AllDeviceInfo[] devices = resp.getDevices();
            if (!ObjectUtil.isEmpty(devices)) {
                List<QueryDeviceResp.Payload> payloads = Arrays.stream(devices)
                        .map(device -> new QueryDeviceResp.Payload(device))
                        .collect(Collectors.toList());
                queryDeviceResp.setPayloads(payloads);
            }
        }
        return queryDeviceResp;
    }

    @Override
    public QueryDeviceResp queryDevice(String deviceId) {
        Assert.notBlank(deviceId, "deviceId不能为空");
        QueryDeviceReq queryDeviceReq = new QueryDeviceReq();
        queryDeviceReq.setDeviceIds(Arrays.asList(deviceId));
        return this.listDevice(queryDeviceReq);
    }

    @Override
    public ModifyDeviceResp modifyDevice(ModifyDeviceReq modifyDeviceReq) {
        try {
            Assert.notNull(modifyDeviceReq, "设备数据异常");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }
        TXModifyDeviceReq req = new TXModifyDeviceReq();
        req.setDeviceId(modifyDeviceReq.getDeviceId());
        req.setDeviceName(modifyDeviceReq.getDeviceId());
        req.setPassword(modifyDeviceReq.getPassword());

        TXModifyDeviceResp resp = this.txModifyDevice(req);
        // 解析响应数据
        ModifyDeviceResp modifyDeviceResp = new ModifyDeviceResp();
        String status = resp.getStatus();
        if ("OK".equals(status)) {
            modifyDeviceResp.setCode(0);
        } else {
            modifyDeviceResp.setCode(1);
        }
        return modifyDeviceResp;
    }

    @Override
    public RemoveDeviceResp removeDevice(RemoveDeviceReq removeDeviceReq) {
        try {
            Assert.notNull(removeDeviceReq, "删除设备数据异常");
            Assert.notBlank(removeDeviceReq.getDeviceId(), "deviceId不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 设置删除设备请求数据
        DeleteDeviceRequest req = new DeleteDeviceRequest();
        req.setDeviceId(removeDeviceReq.getDeviceId());

        DeleteDeviceResponse resp = null;
        try {
            resp = this.httpClient().DeleteDevice(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("删除云设备失败");
        }

        // 解析响应数据
        RemoveDeviceResp removeDeviceResp = new RemoveDeviceResp();
        if (TencentRequestState.OK.getValue().equals(resp.getStatus())) {
            removeDeviceResp.setCode(0);
        } else {
            removeDeviceResp.setCode(1);
        }

        return removeDeviceResp;
    }

    @Override
    public DeviceConstant.DeviceState queryDeviceState(String deviceId) {
        return super.queryDeviceState(deviceId);
    }

    @Override
    public DeviceConstant.DeviceType queryDeviceType(String deviceId) {
        return super.queryDeviceType(deviceId);
    }

    @Override
    public TXCreateDeviceResp txCreateDevice(TXCreateDeviceReq txCreateDeviceReq) {
        try {
            Assert.notNull(txCreateDeviceReq, "创建设备数据异常");
            Assert.notBlank(txCreateDeviceReq.getNickName(), "nickName不能为空");
            Assert.notBlank(txCreateDeviceReq.getPassword(), "password不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }
        CreateDeviceRequest req = BeanUtil.copyProperties(txCreateDeviceReq, CreateDeviceRequest.class);
        CreateDeviceResponse resp = null;
        try {
            resp = this.httpClient().CreateDevice(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("云设备创建失败：", e);
        }
        TXCreateDeviceResp txCreateDeviceResp = new TXCreateDeviceResp();
        if (!ObjectUtil.isEmpty(resp)) {
            BeanUtil.copyProperties(resp, txCreateDeviceResp);
        }
        return txCreateDeviceResp;
    }

    @Override
    public TXRemoveDeviceResp txRemoveDevice(TXRemoveDeviceReq tXRemoveDeviceReq) {
        try {
            Assert.notNull(tXRemoveDeviceReq, "删除设备请求参数异常");
            Assert.notBlank(tXRemoveDeviceReq.getDeviceId(), "deviceId不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }
        DeleteDeviceRequest req = BeanUtil.copyProperties(tXRemoveDeviceReq, DeleteDeviceRequest.class);
        DeleteDeviceResponse resp = null;
        try {
            resp = this.httpClient().DeleteDevice(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("删除云设备失败: ", e);
        }
        TXRemoveDeviceResp txRemoveDeviceResp = new TXRemoveDeviceResp();
        if (!ObjectUtil.isEmpty(resp)) {
            BeanUtil.copyProperties(resp, txRemoveDeviceResp);
        }
        return txRemoveDeviceResp;
    }

    @Override
    public TXQueryDeviceResp txListDevice(TXQueryDeviceReq txQueryDeviceReq) {
        DescribeAllDeviceListRequest req = BeanUtil.copyProperties(txQueryDeviceReq, DescribeAllDeviceListRequest.class);
        DescribeAllDeviceListResponse resp = null;
        try {
            resp = this.httpClient().DescribeAllDeviceList(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("查询云设备失败：", e);
        }
        TXQueryDeviceResp txQueryDeviceResp = new TXQueryDeviceResp();
        if (!ObjectUtil.isEmpty(resp)) {
            BeanUtil.copyProperties(resp, txQueryDeviceResp);
        }
        return txQueryDeviceResp;
    }

    @Override
    public TXQueryDeviceResp txQueryDevice(List<String> deviceIds) {
        try {
            Assert.notEmpty(deviceIds, "deviceIds不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }
        return this.txListDevice(new TXQueryDeviceReq(deviceIds));
    }

    @Override
    public TXModifyDeviceResp txModifyDevice(TXModifyDeviceReq txModifyDeviceReq) {
        try {
            Assert.notNull(txModifyDeviceReq, "修改云设备数据异常");
            Assert.notBlank(txModifyDeviceReq.getDeviceId(), "deviceId不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }
        // 修改用户名
        if (!StrUtil.isBlank(txModifyDeviceReq.getDeviceName())) {
            ModifyDeviceDataRequest req = BeanUtil.copyProperties(txModifyDeviceReq, ModifyDeviceDataRequest.class);
            ModifyDeviceDataResponse nameResp = null;
            try {
                nameResp = this.httpClient().ModifyDeviceData(req);
            } catch (TencentCloudSDKException e) {
                throw new NewlyDeviceException("修改云设备用户名失败: ", e);
            }
        }
        // 修改密码
        if (!StrUtil.isBlank(txModifyDeviceReq.getPassword())) {
            UpdateDevicePassWordRequest req = BeanUtil.copyProperties(txModifyDeviceReq, UpdateDevicePassWordRequest.class);
            UpdateDevicePassWordResponse pwdResp = null;
            try {
                pwdResp = this.httpClient().UpdateDevicePassWord(req);
            } catch (TencentCloudSDKException e) {
                throw new NewlyDeviceException("修改云设备密码失败: ", e);
            }
        }
        return new TXModifyDeviceResp("OK");
    }

    @Override
    public TXQueryChannelResp txListChannel(TXQueryChannelReq txQueryChannelReq) {
        DescribeIPCChannelsRequest req = null;
        if (!ObjectUtil.isEmpty(txQueryChannelReq)) {
            req = BeanUtil.copyProperties(txQueryChannelReq, DescribeIPCChannelsRequest.class);
        }
        DescribeIPCChannelsResponse resp = null;
        try {
            resp = this.httpClient().DescribeIPCChannels(req);
        } catch (TencentCloudSDKException e) {
            throw new NewlyDeviceException("查询云设备通道失败：", e);
        }
        TXQueryChannelResp txQueryChannelResp = new TXQueryChannelResp();
        if (!ObjectUtil.isEmpty(resp)) {
            BeanUtil.copyProperties(resp, txQueryChannelResp);
        }
        return txQueryChannelResp;
    }
}
